/*==============================================================================
             Copyright (c) 2009 - All rights reserved
================================================================================
File description:

    Preview function definition

================================================================================
      Date            Name                    Description of Change
15-Sep-2009  Xiaofeng.Gu                    Written
$HISTORY$
==============================================================================*/
#include "stdafx.h"
#include "Preview.h"
#include "Global.h"
#include <math.h>
#include "MathUtil.h"

CPreviewGraphics::CPreviewGraphics(CGViewer* pViewer)
: m_dPreviewDistance(1.0),
  m_pViewer(pViewer),
  m_pPlatform(NULL),
  m_pPlotter(NULL)
{
	m_pPlatform = m_pViewer->GetParent();
	m_pPlotter = m_pPlatform->GetGraphPlotter();
}

CPreviewGraphics::~CPreviewGraphics()
{
}

////////////////////////////////////////////////////////////////
CLineArrowGraphics::CLineArrowGraphics(CGViewer* pViewer)
: CPreviewGraphics(pViewer),
  m_dLength(1.0)
{
}

CLineArrowGraphics::~CLineArrowGraphics()
{
}

void CLineArrowGraphics::InitializeByPixel(int pixelLenth)
{
	m_iPixelLenth = pixelLenth;

	CCamera* pCamera = m_pViewer->GetCamera();

	m_dPreviewDistance = (pCamera->m_Eye - m_oBasePt).Length();
	m_oDirection.Identify();

	int basePtX, basePtY;
	m_pViewer->ModelSpaceToView(m_oBasePt, basePtX, basePtY);

	CVec endPt = m_oBasePt + m_oDirection * m_dLength;
	int endPtX, endPtY;
	m_pViewer->ModelSpaceToView(endPt, endPtX, endPtY);

	int iLength = (int)(sqrt((double)((endPtX - basePtX) * (endPtX - basePtX) + (endPtY - basePtY) * (endPtY - basePtY))));
	m_dLength = m_iPixelLenth * m_dLength / (iLength * 1.0);
}

void CLineArrowGraphics::Render()
{
	Streams oStreams;

	CCamera* pCamera = m_pViewer->GetCamera();
	CVec eye = pCamera->m_Eye;

	CVec baseToEye = eye - m_oBasePt;
	double length = baseToEye.Length();
	baseToEye.Identify();
	CVec startPt;
	if (fabs(length - m_dPreviewDistance) > DELTA)
	{
		startPt = eye - baseToEye * m_dPreviewDistance;
	}
	else
	{
		return;
	}

	m_oDirection.Identify();

	oStreams.push_back(startPt[0]);
	oStreams.push_back(startPt[1]);
	oStreams.push_back(startPt[2]);
	oStreams.push_back(m_oDirection[0]);
	oStreams.push_back(m_oDirection[1]);
	oStreams.push_back(m_oDirection[2]);
	oStreams.push_back(m_dLength);
	oStreams.push_back(m_dLength / 4.0);

	
	m_pPlotter->Plot(CGraphPlotter::eLineArrow, oStreams);
}

///////////////////////////////////////////////////////////////////////////
CCoordinateSystemGraphics::CCoordinateSystemGraphics(CGViewer* pViewer)
: CPreviewGraphics(pViewer),
  m_x(0),
  m_y(0),
  m_dLength(1.0),
  m_bInit(false)
{
}

CCoordinateSystemGraphics::~CCoordinateSystemGraphics()
{
}

void CCoordinateSystemGraphics::InitializeByPixel(int pixelLenth)
{
	m_iPixelLenth = pixelLenth;

	int w = 0, h = 0;
	m_pViewer->GetViewRange(w, h);
	SetFixedPosition(w / 5.0, (h - h/5.0));

	CGraphicsManager* pManager = m_pPlatform->GetManager();
	pManager->Add(this);

	CSKGlobal::GetMainView()->UpdateView();

	m_bInit = true;
}

void CCoordinateSystemGraphics::Render()
{
	CCamera* pCamera = m_pViewer->GetCamera();

	CVec eye = pCamera->m_Eye;

	CVec pt;
	m_pViewer->ViewToModelSpace(m_x, m_y, pt);
	m_oBasePt = pt;

	CVec V = m_oBasePt - eye;
	V.Identify();

	CVec pt2;
	m_pViewer->ViewToModelSpace(m_x + m_iPixelLenth, m_y, pt2);

	double dPtDistance = (pt2 - pt).Length();
	m_dPreviewDistance = (eye - m_oBasePt).Length();
	m_dPreviewDistance = m_dPreviewDistance / dPtDistance;

	m_oBasePt = eye + V * m_dPreviewDistance;

	Streams oStreams;
	oStreams.clear();
	oStreams.push_back(m_oBasePt[0]);
	oStreams.push_back(m_oBasePt[1]);
	oStreams.push_back(m_oBasePt[2]);
	oStreams.push_back(1);
	oStreams.push_back(0);
	oStreams.push_back(0);
	oStreams.push_back(m_dLength);
	oStreams.push_back(m_dLength / 4.0);
	m_pPlotter->SetColor(255, 0, 0);
	m_pPlotter->Plot(CGraphPlotter::eLineArrow, oStreams);

	oStreams.clear();
	oStreams.push_back(m_oBasePt[0]);
	oStreams.push_back(m_oBasePt[1]);
	oStreams.push_back(m_oBasePt[2]);
	oStreams.push_back(0);
	oStreams.push_back(1);
	oStreams.push_back(0);
	oStreams.push_back(m_dLength);
	oStreams.push_back(m_dLength / 4.0);
	m_pPlotter->SetColor(0, 255, 0);
	m_pPlotter->Plot(CGraphPlotter::eLineArrow, oStreams);

	oStreams.clear();
	oStreams.push_back(m_oBasePt[0]);
	oStreams.push_back(m_oBasePt[1]);
	oStreams.push_back(m_oBasePt[2]);
	oStreams.push_back(0);
	oStreams.push_back(0);
	oStreams.push_back(1);
	oStreams.push_back(m_dLength);
	oStreams.push_back(m_dLength / 4.0);
	m_pPlotter->SetColor(0, 0, 255);
	m_pPlotter->Plot(CGraphPlotter::eLineArrow, oStreams);
}